"""
 *  Copyright (c) 2010 cul.de.sac.code@gmail.com
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
"""

from xmp import *

SXMPFiles.Initialize()
SXMPMeta.Initialize()

class MetaFile(object):
    class Mode(object):
        ro  = kXMPFiles_OpenForRead   | kXMPFiles_OpenOnlyXMP # read only
        rw  = kXMPFiles_OpenForUpdate | kXMPFiles_OpenOnlyXMP # read write

    @staticmethod
    def Initialize():
        SXMPFiles.Initialize()
        SXMPMeta.Initialize()

    @staticmethod
    def Terminate():
        SXMPFiles.Terminate()
        SXMPMeta.Terminate()

    def __del__(self, path=None):
        self.CloseFile(True)

    def __init__(self, path=None, format=kXMP_UnknownFile, mode=Mode.ro):
        self._files = None
        if path is not None:
            self.OpenFile(path, format, mode)
        else:
            self.meta = SXMPMeta()

    def __repr__(self):
        return self.meta.SerializeToBuffer()

    def OpenFile(self, path, format=kXMP_UnknownFile, mode=Mode.ro):
        self.CloseFile(True)
        self._mode = mode
        self._files = SXMPFiles()
        self._files.OpenFile(path, format, mode)
        t = self._files.GetXMP()
        self.meta = t[0] if t else SXMPMeta()

    def CloseFile(self, abandonChanges=False):
        if self._files is not None:
            if not abandonChanges and kXMPFiles_OpenForUpdate == (self._mode & kXMPFiles_OpenForUpdate):
                #if(self.meta.CanPutXMP(meta)):
                self._files.PutXMP(self.meta)

            self._files.CloseFile()
            self._files = None
            self._mode = None

    @property
    def author(self):
        t = self.meta.GetArrayItem(kXMP_NS_DC, "creator", 1)
        return t[0] if t else None

    @author.setter
    def author(self, value):
        if self.meta.DoesArrayItemExist (kXMP_NS_DC, "creator", 1):
            self.meta.SetArrayItem(kXMP_NS_DC, "creator", 1, value)
        else:
            self.meta.AppendArrayItem(kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered, value)

    @property
    def headline(self):
        t = self.meta.GetProperty(kXMP_NS_Photoshop, "Headline")
        return t[0] if t else None

    @headline.setter
    def headline(self, value):
        self.meta.SetProperty(kXMP_NS_Photoshop, "Headline", value)

    @property
    def description(self):
        t = self.meta.GetLocalizedText(kXMP_NS_DC, "description", "en", "en-US")
        return t[0] if t else None

    @description.setter
    def description(self, value):
        t = self.meta.SetLocalizedText(kXMP_NS_DC, "description", "en", "en-US", value)
        
    @property
    def keywords(self):
        k = []
        arrSize = self.meta.CountArrayItems(kXMP_NS_DC, "subject")
        for i in range(1, arrSize+1):
            k.append(self.meta.GetArrayItem(kXMP_NS_DC, "subject", i)[0])
        return k

    @keywords.setter
    def keywords(self, value):
        k = []
        self.meta.DeleteProperty(kXMP_NS_DC, "subject")
        for i in range(0, len(value)):
            self.meta.AppendArrayItem(kXMP_NS_DC, "subject", kXMP_PropValueIsArray, value[i])

    def hasKeyword(self, keyword):
        return keyword in self.keywords()
 
    @property
    def dateCreated(self):
        t = self.meta.GetProperty_Date(kXMP_NS_Photoshop, "DateCreated")
        return t[0] if t else None

    @dateCreated.setter
    def dateCreated(self, value):
        self.meta.SetProperty_Date(kXMP_NS_Photoshop, "DateCreated", value)

    @property
    def location(self):
        t = self.meta.GetProperty(kXMP_NS_IPTCCore, "Location")
        return t[0] if t else None

    @location.setter
    def location(self, value):
        self.meta.GetProperty(kXMP_NS_IPTCCore, "Location", value)

    @property
    def city(self):
        t = self.meta.GetProperty(kXMP_NS_Photoshop, "City")
        return t[0] if t else None
 
    @city.setter
    def city(self, value):
        self.meta.SetProperty(kXMP_NS_Photoshop, "City", value)

    @property
    def state(self):
        t = self.meta.GetProperty(kXMP_NS_Photoshop, "State")
        return t[0] if t else None
 
    @state.setter
    def state(self, value):
        self.meta.SetProperty(kXMP_NS_Photoshop, "State", value)

    @property
    def country(self):
        t = self.meta.GetProperty(kXMP_NS_Photoshop, "Country")
        return t[0] if t else None

    @country.setter
    def country(self, value):
        self.meta.SetProperty(kXMP_NS_Photoshop, "Country", value)
 
    @property
    def title(self):
        t = self.meta.GetLocalizedText(kXMP_NS_DC, "title", "en", "en-US")
        return t[0] if t else None
        
    @title.setter
    def title(self, value):
        self.meta.SetLocalizedText(kXMP_NS_DC, "title", "en", "en-US", value)

    @property
    def position(self):
        lat = self.meta.GetProperty(kXMP_NS_EXIF, "GPSLatitude")
        lon = self.meta.GetProperty(kXMP_NS_EXIF, "GPSLongitude")
        return (lat[0], lon[0]) if lat and lon else ()

    @position.setter
    def position(self, value):
        self.meta.SetProperty(kXMP_NS_EXIF, "GPSLatitude", value[0])
        self.meta.SetProperty(kXMP_NS_EXIF, "GPSLongitude", value[1])

    @property
    def dateTimeOriginal(self):
        t = self.meta.GetProperty_Date(kXMP_NS_EXIF, "DateTimeOriginal")
        return t[0] if t else None

    #@datetimeOriginal.setter
    #def datetimeOriginal(self, value):
    #    self.meta.SetProperty_Date(kXMP_NS_EXIF, "DateTimeOriginal", value)

    @property
    def rating(self):
        t = self.meta.GetProperty_Int(kXMP_NS_XMP, "Rating")
        return t[0] if t else None

    @rating.setter
    def rating(self, value):
        self.meta.SetProperty_Int(kXMP_NS_XMP, "Rating", value)

    @property
    def label(self):
        t = self.meta.GetProperty(kXMP_NS_XMP, "Label")
        return t[0] if t else None

    @label.setter
    def label(self, value):
        self.meta.SetProperty(kXMP_NS_XMP, "Label", value)
